-------------------模块区-------------------
local logger = require("dx_logger")
local util = require("dx_util")
local mqtt = require("dx_mqtt")

-------------------变量区-------------------
-- mqtt连接信息，可自定义修改值
local conn_args = {
    host = "192.168.212.95",
    port = "5555",
    id = "device_clientid"
}
-- 订阅topic（支持批量订阅）
local subscribes = {
    "test/topic/123",
    "test/topic/124"
}

local mqtt_common = {}

-------------------函数区-------------------

-- 处理收到订阅的主题消息
function mqtt_common.callback(topic, payload)
    logger.debug("======================")
    logger.debug("topic", topic)
    logger.debug("payload", payload)
    logger.debug("======================")
    -- 发送消息
    mqtt_client:publish("20220901/cmd/control_reply", "success")
end

-- 创建一个mqtt client实例
function mqtt_common.create_client(args)
    -- 指定服务器ip、port、收到订阅的主题消息时的调用函数
    _G.mqtt_client = mqtt.client.create(args.host, args.port, mqtt_common.callback)
    logger.debug("[创建mqtt实例] 成功")
end

-- 建立mqtt连接
function mqtt_common.create_connect(args)
    -- mqtt_client:connect参数
    -- MQTT客户端标识符(最多23个字符)
    local connect_error = mqtt_client:connect(args.id)
    while connect_error ~= nil do
        -- 错误重连
        logger.error("[mqtt连接] " .. connect_error)
        util.sleep(1)
        connect_error = mqtt_client:connect(args.id)
    end
    logger.debug("[mqtt连接] 成功")
end

-- mqtt消息订阅
function mqtt_common.create_subscribe(args)
    args.topic_s = subscribes
    mqtt_client:subscribe(subscribes)
    logger.debug("[mqtt消息订阅] 成功")
end

-- 处理接收到的消息并维护保活PING消息。必须定期调用此函数，来维持链接并为传入的订阅主题消息提供服务
function mqtt_common.Keep_alive()
    local error_message = nil
    while not error_message do
        error_message = mqtt_client:handler()
        os.execute("sleep " .. 1)
        if (error_message == nil) then
            -- 可以在这里定制业务逻辑
            -- logger.debug("mqtt服务运行中...")
        end
    end
    return error_message
end

function mqtt_common.error(error_message, args)
    if (error_message == nil) then
        -- 如果mqtt服务没报错代表正常退出，断开后不会重连
        mqtt_client:unsubscribe(args.topic_s)
        mqtt_client:destroy()
        logger.debug("mqtt服务停止，订阅&连接已释放")
        return false
    else
        logger.debug("mqtt通道异常，", error_message)
        return true
    end
end

function mqtt_common.init()
    local flag = true
    while flag do
        -- 异常停止会导致重连
        mqtt_common.create_client(conn_args)
        mqtt_common.create_connect(conn_args)
        mqtt_common.create_subscribe(conn_args)
        local error_message = mqtt_common.Keep_alive()
        flag = mqtt_common.error(error_message, conn_args)
        util.sleep(5)
    end
end

-------------------主流程-------------------

return mqtt_common
